home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 2: Applications / Linux Cubed Series 2 - Applications.iso / utils / shell / cdialog-.9a / cdialog- / cdialog-0.9a / dialog.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-01-15  |  15.0 KB  |  550 lines

  1. /*
  2.  *  cdialog - Display simple dialog boxes from shell scripts
  3.  *
  4.  *  AUTHOR: Savio Lam (lam836@cs.cuhk.hk)
  5.  *
  6.  *  This program is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU General Public License
  8.  *  as published by the Free Software Foundation; either version 2
  9.  *  of the License, or (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include "dialog.h"
  22.  
  23. static void Usage (const char *name);
  24. static int howmany_tags(int argc, const char * const * argv, int offset, int group);
  25. static int arg_rest( int argc, const char * const * argv, int offset );
  26.  
  27. /* globals */
  28. char *backtitle, *lock_refresh, *lock_tailbg_refreshed,
  29.     *lock_tailbg_exit;
  30. int beep_signal, is_tailbg = 0, print_siz, cr_wrap, size_err,
  31.     tab_len, tab_correct;
  32. int begin_x, begin_y, begin_set, aspect_ratio, screen_initialized = 0;
  33. pid_t tailbg_pids[MAX_TAILBG], tailbg_lastpid = 0, tailbg_nokill_pids[MAX_TAILBG], tailbg_nokill_lastpid = 0;
  34. int cant_kill;
  35.  
  36. int separate_output;    /* local file */
  37.  
  38. typedef int (jumperFn) (const char *title, int argc, const char * const * argv, int offset, int *offset_add);
  39.  
  40. struct Mode {
  41.     char *name;
  42.     int argmin, argmax;
  43.     jumperFn *jumper;
  44. };
  45.  
  46. jumperFn j_yesno, j_msgbox, j_infobox, j_textbox, j_menu;
  47. jumperFn j_checklist, j_radiolist, j_inputbox, j_guage;
  48. jumperFn j_tailbox, j_tailboxbg;
  49.  
  50. /*
  51.  * All functions are used in the slackware root disk, apart from "guage"
  52.  */
  53.  
  54. static struct Mode modes[] =
  55. {
  56.     {"--yesno", 5, 5, j_yesno},
  57.     {"--msgbox", 5, 5, j_msgbox},
  58.     {"--infobox", 5, 5, j_infobox},
  59.     {"--textbox", 5, 5, j_textbox},
  60.     {"--menu", 8, 0, j_menu},
  61.     {"--checklist", 9, 0, j_checklist},
  62.     {"--radiolist", 9, 0, j_radiolist},
  63.     {"--inputbox", 5, 6, j_inputbox},
  64. #ifdef HAVE_GUAGE
  65.     {"--guage", 6, 6, j_guage},
  66. #endif
  67. #ifdef HAVE_TAILBOX
  68.     {"--tailbox", 5, 5, j_tailbox},
  69.     {"--tailboxbg", 5, 5, j_tailboxbg},
  70. #endif
  71.     {NULL, 0, 0, NULL}
  72. };
  73.  
  74. static struct Mode *modePtr;
  75.  
  76. #ifdef LOCALE
  77. #include <locale.h>
  78. #endif
  79.  
  80. int
  81. main (int argc, const char * const * argv)
  82. {
  83.     int offset = 0, clear_screen, end_common_opts, retval = 0, sleep_secs,
  84.         beep_after_signal, tab_set, offset_add, esc_pressed = 0;
  85.     char *title, separate_str[MAX_LEN];
  86.  
  87. #ifdef LOCALE
  88.     (void) setlocale (LC_ALL, "");
  89. #endif
  90.  
  91.     if (argc == 2) {     /* if we don't want clear screen */
  92.       if (!strcmp(argv[1], "--print-maxsize" ))
  93.       {
  94.         initscr ();
  95.         fprintf(stderr, "MaxSize: %d, %d\n", SLINES, SCOLS);
  96.         endwin ();
  97.       }
  98.       else if (!strcmp(argv[1], "--print-version" ))
  99.       {
  100.         fprintf(stderr, "Version: %s\n", VERSION);
  101.       }
  102.  
  103.       return 0;
  104.     }
  105.  
  106.     init_dialog ();
  107.  
  108.     if (argc < 2)
  109.     Usage (argv[0]);
  110. #ifdef HAVE_RC_FILE
  111.  
  112.     else if (!strcmp (argv[1], "--create-rc"))
  113. #ifdef HAVE_NCURSES
  114.     {
  115.     if (argc != 3)
  116.         Usage (argv[0]);
  117.     end_dialog();
  118.     create_rc (argv[2]);
  119.     return 0;
  120.     }
  121. #else
  122.     exiterr("\nThis option is currently unsupported on your system.\n");
  123. #endif
  124. #endif
  125.  
  126.  if ((lock_refresh=make_lock_filename("/tmp/.lock_fileXXXXXX")) == NULL ||
  127.      (lock_tailbg_refreshed=make_lock_filename("/tmp/.lock_tailbgXXXXXX")) == NULL ||
  128.      (lock_tailbg_exit=make_lock_filename("/tmp/.lock_exitXXXXXX")) == NULL)
  129.     exiterr("\nInternal error: can't make lock files.\n");
  130.  
  131.  strcpy (separate_str, DEFAULT_SEPARATE_STR);
  132.  
  133.  while (offset < argc-1 && !esc_pressed) {
  134.   title = NULL; clear_screen = 0; end_common_opts = 0;
  135.   separate_output = 0; backtitle = NULL; sleep_secs = 0;
  136.   begin_set = 0; begin_x = 0; begin_y = 0; aspect_ratio = 0;
  137.   beep_signal = 0; beep_after_signal = 0; print_siz = 0;
  138.   cr_wrap = 0; size_err = 0; tab_set = 0; tab_correct = 0;
  139.   cant_kill = 0;
  140.  
  141.   while (offset < argc - 1 && !end_common_opts) {    /* Common options */
  142.     if (!strcmp(argv[offset+1], "--title")) {
  143.       if (argc-offset < 3 || title != NULL)    /* No two "--title" please! */
  144.         Usage(argv[0]);
  145.       else {
  146.         title = argv[offset+2];
  147.         offset += 2;
  148.       }
  149.     }
  150.     else if (!strcmp(argv[offset+1], "--backtitle" ))
  151.     {
  152.       if (backtitle != NULL)
  153.         Usage(argv[0]);
  154.       else
  155.       {
  156.         backtitle = argv[offset+2];
  157.         offset += 2;
  158.       }
  159.     }
  160.     else if (!strcmp(argv[offset+1], "--separate-widget" ))
  161.     {
  162.       strcpy(separate_str, argv[offset+2]);
  163.       offset += 2;
  164.     }
  165.     else if (!strcmp(argv[offset+1], "--separate-output" ))
  166.     {
  167.         separate_output = 1;
  168.         offset++;
  169.     }
  170.     else if (!strcmp(argv[offset+1], "--cr-wrap" ))
  171.     {
  172.         cr_wrap = 1;
  173.         offset++;
  174.     }
  175.     else if (!strcmp(argv[offset+1], "--no-kill" ))
  176.     {
  177.         cant_kill = 1;
  178.         offset++;
  179.     }
  180.     else if (!strcmp(argv[offset+1], "--size-err" ))
  181.     {
  182.         size_err = 1;
  183.         offset++;
  184.     }
  185.     else if (!strcmp(argv[offset+1], "--beep" ))
  186.     {
  187.         beep_signal = 1;
  188.         offset++;
  189.     }
  190.     else if (!strcmp(argv[offset+1], "--beep-after" ))
  191.     {
  192.         beep_after_signal = 1;
  193.         offset++;
  194.     }
  195.     else if (!strcmp(argv[offset+1], "--shadow" ))
  196.     {
  197.         use_shadow = TRUE;
  198.         offset++;
  199.     }
  200.     else if (!strcmp(argv[offset+1], "--no-shadow" ))
  201.     {
  202.         use_shadow = FALSE;
  203.         offset++;
  204.     }
  205.     else if (!strcmp(argv[offset+1], "--print-size" ))
  206.     {
  207.         print_siz = 1;
  208.         offset++;
  209.     }
  210.     else if (!strcmp(argv[offset+1], "--print-maxsize" ))
  211.     {
  212.         fprintf(stderr, "MaxSize: %d, %d\n", SLINES, SCOLS);
  213.         offset++;
  214.     }
  215.     else if (!strcmp(argv[offset+1], "--print-version" ))
  216.     {
  217.         fprintf(stderr, "Version: %s\n", VERSION);
  218.         offset++;
  219.     }
  220.     else if (!strcmp(argv[offset+1], "--tab-correct" ))
  221.     {
  222.         tab_correct = 1;
  223.         offset++;
  224.     }
  225.     else if (!strcmp(argv[offset+1], "--sleep")) {
  226.       if (argc-offset < 3 || sleep_secs != 0)
  227.         Usage(argv[0]);
  228.       else {
  229.         sleep_secs = atoi(argv[offset+2]);
  230.         offset += 2;
  231.       }
  232.     }
  233.     else if (!strcmp(argv[offset+1], "--tab-len")) {
  234.       if (argc-offset < 3 || tab_set != 0)
  235.         Usage(argv[0]);
  236.       else {
  237.         tab_len = atoi(argv[offset+2]);
  238.         tab_set = 1;
  239.         offset += 2;
  240.       }
  241.     }
  242.     else if (!strcmp(argv[offset+1], "--aspect")) {
  243.       if (argc-offset < 3 || aspect_ratio != 0)
  244.         Usage(argv[0]);
  245.       else {
  246.         aspect_ratio=atoi(argv[offset+2]);
  247.         offset += 2;
  248.       }
  249.     }
  250.     else if (!strcmp(argv[offset+1], "--begin")) {
  251.       if (argc-offset < 4 || begin_set != 0)
  252.         Usage(argv[0]);
  253.       else {
  254.         begin_y = atoi(argv[offset+2]);
  255.         begin_x = atoi(argv[offset+3]);
  256.         begin_set=1;
  257.         offset += 3;
  258.       }
  259.     }
  260.     else if (!strcmp(argv[offset+1], "--clear")) {
  261.       if (clear_screen)    /* Hey, "--clear" can't appear twice! */
  262.         Usage(argv[0]);
  263.       else if (argc == 2) {    /* we only want to clear the screen */
  264.         killall_bg();
  265.         refresh();
  266.         end_dialog();
  267.         return 0;
  268.       }
  269.       else {
  270.         clear_screen = 1;
  271.         offset++;
  272.       }
  273.     }
  274.     else    /* no more common options */
  275.       end_common_opts = 1;
  276.   }
  277.  
  278.   /* if (separate_output==1 and no-checklist) or (no more options) ... */
  279.   if ((strcmp(argv[offset+1], "--checklist") && (separate_output == 1)) || (argc-1 == offset))
  280.     Usage(argv[0]);
  281.  
  282.   if (tab_set == 0)
  283.     tab_len=TAB_LEN;
  284.  
  285.   if (aspect_ratio == 0)
  286.     aspect_ratio=DEFAULT_ASPECT_RATIO;
  287.  
  288.   put_backtitle();
  289.  
  290.     /* use a table to look for the requested mode, to avoid code duplication */
  291.  
  292.     for (modePtr = modes; modePtr->name; modePtr++)    /* look for the mode */
  293.     if (!strcmp (argv[offset + 1], modePtr->name))
  294.         break;
  295.  
  296.     if (!modePtr->name)
  297.     Usage (argv[0]);
  298.     if (arg_rest(argc, argv, offset) < modePtr->argmin)
  299.     Usage (argv[0]);
  300.     if (modePtr->argmax && arg_rest(argc, argv, offset) > modePtr->argmax)
  301.     Usage (argv[0]);
  302.  
  303.     retval = (*(modePtr->jumper)) (title, argc, argv, offset, &offset_add);
  304.  
  305.     if (retval == -1) 
  306.         esc_pressed = 1;
  307.  
  308.     offset+=offset_add;
  309.  
  310.     if (!esc_pressed) {
  311.  
  312.       if (beep_after_signal)        beep();
  313.  
  314.       if (sleep_secs)       sleep(sleep_secs);
  315.  
  316.       if (clear_screen)
  317.     attr_clear (stdscr, LINES, COLS, screen_attr);
  318.  
  319.       if (offset+1 < argc) {
  320.         if (!strcmp(argv[offset+1], "--and-widget")) {
  321.           fprintf(stderr, separate_str);
  322.           offset++;
  323.         } else
  324.           Usage(argv[0]);
  325.       }
  326.     }
  327.     
  328.  }
  329.  
  330.  quitall_bg(); /* instead of killall_bg() */
  331.  refresh();
  332.  end_dialog();
  333.  return retval;
  334. }
  335. /* End of main() */
  336.  
  337. /*
  338.  * Print program usage
  339.  */
  340. static void 
  341. Usage(const char *name)
  342. {
  343.   char *str=(char *) malloc((size_t) 300); /* change this number for a longer string */
  344.  
  345.   sprintf(str, "\
  346. \ndialog version 0.3, by Savio Lam (lam836@cs.cuhk.hk).\
  347. \n  patched to version 0.4 by Stuart Herbert (S.Herbert@shef.ac.uk)\
  348. \n    cdialog (ComeOn Dialog!) version %s by Pako (demarco_p@abramo.it)\
  349. \n\
  350. \n* Display dialog boxes from shell scripts *\
  351. \n\
  352. \nUsage: %s <Common options> <Box options> { --and-widget <Common options> <Box options> }\
  353. \n\
  354. \nCommon options: <Global options>\
  355. \n       [--backtitle <backtitle>] [--sleep <secs>] [--beep] [--beep-after]\
  356. \n       [--clear] [--begin <y> <x>] [--aspect <ratio>] [--print-size]\
  357. \n       [--print-maxsize] [--size-err] [--separate-output] [--cr-wrap]\
  358. \n       [--tab-len <n>] [--tab-correct] [--print-version] [--no-kill]\
  359. \n       [--title <title>]\
  360. \n\
  361. \nGlobal options: [--shadow] [--no-shadow] [--separate-widget \"<str>\"]\
  362. \n\
  363. \nBox options:\
  364. \n  --yesno     <text> <height> <width>\
  365. \n  --msgbox    <text> <height> <width>\
  366. \n  --infobox   <text> <height> <width>\
  367. \n  --inputbox  <text> <height> <width> [<init>]\
  368. \n  --textbox   <file> <height> <width>\
  369. \n  --menu      <text> <height> <width> <menu height> <tag1> <item1>...\
  370. \n  --checklist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
  371. \n  --radiolist <text> <height> <width> <list height> <tag1> <item1> <status1>...\
  372. \n  --guage     <text> <height> <width> <percent>\
  373. \n  --tailbox   <file> <height> <width>\
  374. \n  --tailboxbg <file> <height> <width>\
  375. \n\
  376. \n (auto-size with height and width = 0. Maximize with height and width = -1)\
  377. \n (global-auto-size if also menu_height/list_height = 0)\
  378. \n", VERSION, name);
  379.  
  380. exiterr(str);
  381. }
  382.  
  383.  
  384. /*
  385.  * In MultiWidget this function is needed to count how many tags
  386.  * a widget (menu, checklist, radiolist) has
  387.  */
  388. int howmany_tags(int argc, const char * const * argv, int offset, int group)
  389. {
  390.   int i, ptr = offset;
  391.  
  392.   while (ptr+group <= argc) { /* quantity control */
  393.     if (!strcmp(argv[ptr], "--and-widget")) break;
  394.     for (i = 1; i < group; i++)
  395.       if (!strcmp(argv[ptr+i], "--and-widget")) /* quality control */
  396.         Usage(argv[0]);
  397.  
  398.     ptr+=group;
  399.   }
  400.   
  401.   if ((ptr != argc) && (ptr+group <= argc) && strcmp(argv[ptr], "--and-widget"))
  402.         Usage(argv[0]);
  403.   
  404.   return (ptr-offset)/group;
  405. }
  406.  
  407. int arg_rest( int argc, const char * const * argv, int offset ) {
  408.     int i=offset;
  409.     
  410.     while (++i < argc) {
  411.         if (!strcmp (argv[i], "--and-widget"))
  412.             break;
  413.     }    
  414.     return i-offset;
  415. }
  416.  
  417. /*
  418.  * These are the program jumpers
  419.  */
  420.  
  421. int
  422. j_yesno (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  423. {
  424.     *offset_add=4;
  425.     return dialog_yesno (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]));
  426. }
  427.  
  428. int
  429. j_msgbox (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  430. {
  431.     *offset_add=4;
  432.     return dialog_msgbox (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]), 1);
  433. }
  434.  
  435. int
  436. j_infobox (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  437. {
  438.     *offset_add=4;
  439.     return dialog_msgbox (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]), 0);
  440. }
  441.  
  442. int
  443. j_textbox (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  444. {
  445.     *offset_add=4;
  446.     return dialog_textbox (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]));
  447. }
  448.  
  449. int
  450. j_menu (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  451. {
  452.     int ret;
  453.     int tags=howmany_tags(ac, av, offset+6, 2);
  454.     *offset_add=5+tags*2;
  455.     ret = dialog_menu (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]),
  456.             atoi (av[offset+5]), tags, av + offset + 6);
  457.     if (ret >= 0) {
  458.     fprintf(stderr, av[offset+ 6 + ret * 2]);
  459.     return 0;
  460.     } else if (ret == -2)
  461.     return 1;    /* CANCEL */
  462.     return ret;        /* ESC pressed, ret == -1 */
  463. }
  464.  
  465. int
  466. j_checklist (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  467. {
  468.     int tags=howmany_tags(ac, av, offset+6, 3);
  469.     *offset_add=5+tags*3;
  470.     return dialog_checklist (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]),
  471.     atoi (av[offset+5]), tags, av + offset + 6, FLAG_CHECK, separate_output);
  472. }
  473.  
  474. int
  475. j_radiolist (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  476. {
  477.     int tags=howmany_tags(ac, av, offset+6, 3);
  478.     *offset_add=5+tags*3;
  479.     return dialog_checklist (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]),
  480.     atoi (av[offset+5]), tags, av + offset + 6, FLAG_RADIO, separate_output);
  481. }
  482.  
  483. int
  484. j_inputbox (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  485. {
  486.     int ret;
  487.     char *init_inputbox=(char *) NULL;
  488.     if (offset+5 < ac)
  489.       if (strcmp(av[offset+5], "--and-widget"))
  490.         init_inputbox=av[offset+5];
  491.  
  492.     *offset_add=4+((init_inputbox == NULL) ? 0 : 1);
  493.     ret = dialog_inputbox (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]),
  494.                 init_inputbox);
  495.     if (ret == 0)
  496.     fprintf(stderr, dialog_input_result);
  497.     return ret;
  498. }
  499.  
  500. #ifdef HAVE_GUAGE
  501. int
  502. j_guage (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  503. {
  504.     *offset_add=5;
  505.     return dialog_guage (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]),
  506.              atoi (av[offset+5]));
  507. }
  508. #endif
  509.  
  510. #ifdef HAVE_TAILBOX
  511. int
  512. j_tailbox (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  513. {
  514.     *offset_add=4;
  515.     return dialog_tailbox (t, av[offset+2], atoi (av[offset+3]), atoi (av[offset+4]));
  516. }
  517.  
  518. int
  519. j_tailboxbg (const char *t, int ac, const char * const * av, int offset, int *offset_add)
  520. {
  521.     if (tailbg_lastpid+1 >= MAX_TAILBG)
  522.       Usage(av[0]);
  523.  
  524.     *offset_add=4;
  525.     refresh(); /* doupdate(); */
  526.     if (cant_kill)
  527.         tailbg_nokill_pids[tailbg_nokill_lastpid]=tailbg_pids[tailbg_lastpid]=fork();
  528.     else
  529.         tailbg_pids[tailbg_lastpid]=fork();
  530.  
  531.     /* warning! here are 2 processes */
  532.  
  533.     if (tailbg_pids[tailbg_lastpid] == 0) {
  534.         if (cant_kill) 
  535.             fprintf (stderr, "%d", (int) getpid());
  536.         is_tailbg = 1;
  537.         dialog_tailboxbg(t, av[offset+2], atoi(av[offset+3]),
  538.                            atoi(av[offset+4]), cant_kill);
  539.                            
  540.         refresh(); /* quitting for signal 15 and --no-kill */
  541.         endwin();
  542.         exit(0);
  543.     }
  544.     if (cant_kill)
  545.         tailbg_nokill_lastpid++;
  546.     tailbg_lastpid++;
  547.     return 0;
  548. }
  549. #endif
  550.